#!/usr/bin/python -u
#----------------------------------------------------------------------
# Name:        build-all.py
# Purpose:     Master build script for building all the wxPython
#              installers and such on all the build machines in
#              my lab, and then distributing the results as needed.
#
#              This will replace the build-all bash script and is
#              needed because the needs of the build have outgrown
#              what I can do with bash.
#
# Author:      Robin Dunn
#
# Created:     05-Nov-2004
# RCS-ID:      $Id$
# Copyright:   (c) 2004 by Total Control Software
# Licence:     wxWindows license
#----------------------------------------------------------------------

import sys
import os
import time
from taskrunner import Job, Task, TaskRunner, Config

#----------------------------------------------------------------------
# Configuration items

CFGFILE = "./distrib/all/build-environ.cfg"
config = Config()
config.read(CFGFILE)

#----------------------------------------------------------------------
# Define all the build tasks

class Job(Job):
    LOGBASE = "./tmp"

#----------------------------------------------------------------------

def getTasks(config_env):
    # Things that need to be done before any of the builds
    initialTask = Task([
        Job("", "distrib/all/build-setup", env=config_env),
        Job("", "distrib/all/build-docs", env=config_env),
        Job("", "distrib/all/build-sources", env=config_env),
        ])
    
    # Build tasks.  Anything that can be done in parallel (depends greatly
    # on the nature of the build machines configurations...) is a separate
    # task.
    

    carbonTask =  Task([
        Job("carbon.26", "distrib/all/build-osx", [config.OSX_HOST_carbon, "2.6", "carbon"], env=config_env),
        Job("carbon.27", "distrib/all/build-osx", [config.OSX_HOST_carbon, "2.7", "carbon"], env=config_env),
        ])

    cocoaTask =  Task([
        Job("cocoa.27", "distrib/all/build-osx", [config.OSX_HOST_cocoa, "2.7", "cocoa"], env=config_env),
        ])

    
    cyclopsTask0 = Task([
        Job("win32-26", "distrib/all/build-windows", ["2.6"], env=config_env),
        Job("win32-27", "distrib/all/build-windows", ["2.7"], env=config_env),
        Job("win64-26", "distrib/all/build-windows", ["2.6", "X64"], env=config_env),
        Job("win64-27", "distrib/all/build-windows", ["2.7", "X64"], env=config_env),
        ])
    

    cyclopsTask1 = Task([
        Job("lucid",   "distrib/all/build-deb", ["cy-ubuntu-opd", "/work/chroot/lucid",   "lucid"], env=config_env),
        Job("lucid64", "distrib/all/build-deb", ["cy-ubuntu-opd", "/work/chroot/lucid64", "lucid64"], env=config_env),
        Job("maverick",   "distrib/all/build-deb", ["cy-ubuntu-opd", "/work/chroot/maverick",   "maverick"], env=config_env),
        Job("maverick64", "distrib/all/build-deb", ["cy-ubuntu-opd", "/work/chroot/maverick64", "maverick64"], env=config_env),
        ])

    cyclopsTask2 = Task([
        # 64-bit builds are now handled w/o a VM, see above
        #Job("win64-26", "distrib/all/build-vmwin", ["cyclops", "WinXP-x64-1", "cy-win64", "2.6", "X64"], env=config_env),
        #Job("win64-27", "distrib/all/build-vmwin", ["cyclops", "WinXP-x64-1", "cy-win64", "2.7", "X64"], env=config_env),
        ])

    cyclopsTask3 = Task([
        Job("etch",   "distrib/all/build-deb", ["cy-ubuntu-opd", "/work/chroot/etch",     "etch"], env=config_env),
        Job("etch64", "distrib/all/build-deb", ["cy-ubuntu-opd", "/work/chroot/etch64",   "etch64"], env=config_env),
        Job("lenny",   "distrib/all/build-deb", ["cy-ubuntu-opd", "/work/chroot/lenny",   "lenny"], env=config_env),
        Job("lenny64", "distrib/all/build-deb", ["cy-ubuntu-opd", "/work/chroot/lenny64", "lenny64"], env=config_env),
        ])
    
    buildTasks = [ carbonTask,
                   cocoaTask,
                   cyclopsTask0,
                   #cyclopsTask1,
                   ##cyclopsTask2,
                   #cyclopsTask3,
                   ]
    
    # Finalization.  This is for things that must wait until all the
    # builds are done, such as copying the installers someplace, sending
    # emails, etc.
    finalizationTask = Task( Job("", "distrib/all/build-finalize", env=config_env) )

    return initialTask, buildTasks, finalizationTask


#----------------------------------------------------------------------

def usage():
    print ""
    print "Usage: build-all [command flags...]"
    print ""
    print "build types:"
    print "   dryrun       Do the build, but don't copy anywhere (default)"
    print "   daily        Do a daily build, copy to starship"
    print "   release      Do a normal release (cantidate) build, copy to starship"
    print ""
    print "optional command flags:"
    print "   skipsource   Don't build the source archives, use the ones"
    print "                already in the staging dir."
    print "   onlysource   Exit after building the source and docs archives"
    print "   skipdocs     Don't rebuild the docs"
    print "   skipwin      Don't do the remote Windows build"
    print "   skiposx      Don't do the remote OSX build"
    print "   skiprpm      Don't do the remote Linux (RPM) build"
    print "   skipdeb      Don't do the remote Linux (DEB) build"
    print "   skipclean    Don't do the cleanup step on the remote builds"
    print "   skipupload   Don't upload the builds to starship"
    print ""
    print "   nocohost     Don't start the coLinux sessions if they are"
    print "                not already online"
    print ""
    

#----------------------------------------------------------------------

def main(args):
    # Make sure we are running in the right directory.  TODO: make
    # this test more robust.  Currenly we just test for the presence
    # of 'wxPython' and 'wx' subdirs.
    if not os.path.isdir("distrib") or not os.path.isdir("wx"):
        print "Please run this script from the root wxPython directory."
        sys.exit(1)
        
    

    # Check command line flags
    for flag in args:
        if flag in ["dryrun", "daily", "release"]:
            config.KIND = flag

        elif flag == "skipsource":
            config.skipsource = "yes"
            
        elif flag == "onlysource":
            config.onlysource = "yes"
            
        elif flag == "skipdocs":
            config.skipdocs = "yes"
            
        elif flag == "skipnewdocs":
            config.skipnewdocs = "yes"
            
        elif flag == "skipwin":
            config.skipwin = "yes"
            
        elif flag == "skiposx":
            config.skiposx = "yes"
            
        elif flag == "skipdeb":
            config.skipdeb = "yes"
            
        elif flag == "skiprpm":
            config.skiprpm = "yes"
            
        elif flag == "skipclean":
            config.skipclean = "yes"
            
        elif flag == "skipupload":
            config.skipupload = "yes"

        elif flag == "nocohost":
            config.startcohost = "no"
            
        else:
            print 'Unknown flag: "%s"' % flag
            usage()
            sys.exit(2)


    # ensure the staging area exists
    if not os.path.exists(config.STAGING_DIR):
        os.makedirs(config.STAGING_DIR)

    # Figure out the wxPython version number, possibly adjusted for being a daily build
    if config.KIND == "daily":
        t = time.localtime()
        config.DAILY = time.strftime("%Y%m%d")   # should it include the hour too?  2-digit year?
        file("DAILY_BUILD", "w").write(config.DAILY)
    sys.path.append('.')
    import setup
    v = config.VERSION = setup.VERSION
    config.VER2 = '.'.join(v.split('.')[:2])

    config_env = config.asDict()
    config_env.update(os.environ)

    initialTask, buildTasks, finalizationTask = getTasks(config_env)

    print "Build getting started at: ", time.ctime()

    # Run the first task, which will create the docs and sources tarballs
    tr = TaskRunner(initialTask)
    rc = tr.run()

    # cleanup the DAILY_BUILD file
    if config.KIND == "daily":
        os.unlink("DAILY_BUILD")

    # Quit now?
    if rc != 0 or config.onlysource == "yes":
        sys.exit(rc)


    # Run the main build tasks
    tr = TaskRunner(buildTasks)
    rc = tr.run()
    if rc != 0:
        sys.exit(rc)


    # when all the builds are done, run the finalization task
    tr = TaskRunner(finalizationTask)
    rc = tr.run()
    if rc != 0:
        sys.exit(rc)

    
    print "Build finished at: ", time.ctime()
    sys.exit(0)




if __name__ == "__main__":
    main(sys.argv[1:])
